package main

import (
	"fmt"
)

const (
	b  = true
	s  = "hello world"
	in = 29
)

var grade = "A"
var marks = 50

var infa interface{}

func main() {

	// if else 条件
	testIfElse()

	// switch 条件
	testSwitch()

	// select 条件
	testSelect()
}

/*
	select 是 Go 中的一个控制结构，类似于用于通信的 switch 语句。每个 case 必须是一个通信操作，要么是发送要么是接收。
	select 随机执行一个可运行的 case。如果没有 case 可运行，它将阻塞，直到有 case 可运行。一个默认的子句应该总是可运行的。
*/
func testSelect() {
	// <- chan 左接右发
	var c1, c2, c3 chan int
	var i1, i2 int
	select {
	case i1 = <-c1:
		fmt.Printf("received ", i1, " from c1\n")
	case c2 <- i2:
		fmt.Printf("send ", i2, " to c2 \n")
	case i3, ok := (<-c3): // same as: i3, ok := <-c3
		if ok {
			fmt.Printf("received ", i3, " from c3\n")
		} else {
			fmt.Printf("c3 is closed\n")
		}
	default:
		fmt.Printf("no communication\n")
	}
}

/**
switch 条件
*/
func testSwitch() {
	/* 定义局部变量 */
	switch marks {
	case 90:
		grade = "A"
	case 80:
		grade = "B"
	case 50, 60, 70:
		grade = "C"
	default:
		grade = "D"
	}
	fmt.Printf("%d分是%s等\n", marks, grade)

	switch {
	case grade == "A":
		fmt.Printf("优秀!\n")
	case grade == "B", grade == "C":
		fmt.Printf("良好\n")
	case grade == "D":
		fmt.Printf("及格\n")
	case grade == "F":
		fmt.Printf("不及格\n")
	default:
		fmt.Printf("差\n")
	}
	fmt.Printf("你的等级是 %s\n", grade)

	// Type Switch
	// switch 语句还可以被用于 type-switch 来判断某个 interface 变量中实际存储的变量类型。
	switch i := infa.(type) {
	case nil:
		fmt.Printf(" x 的类型 :%T", i)
	case int:
		fmt.Printf(" x 的类型 :%T", i)
	case float32:
		fmt.Printf(" x 的类型 :%T", i)
	case string:
		fmt.Printf(" x 的类型 :%T", i)
	case bool:
		fmt.Printf(" x 的类型 :%T", i)
	case float64:
		fmt.Printf(" x 的类型 :%T", i)
	}
	fmt.Println()

	// fallthrough
	// 使用 fallthrough 会强制执行后面的 case 语句，fallthrough 不会判断下一条 case 的表达式结果是否为 true。
	switch {
	case false:
		fmt.Println("1、case 条件语句为 false")
		fallthrough
	case true:
		fmt.Println("2、case 条件语句为 true")
		fallthrough
	case false:
		fmt.Println("3、case 条件语句为 false")
		fallthrough
	case true:
		fmt.Println("4、case 条件语句为 true")
	case false:
		fmt.Println("5、case 条件语句为 false")
		fallthrough
	default:
		fmt.Println("6、默认 case")
	}
}

/*
	if else 条件语句
*/
func testIfElse() {
	if b {
		fmt.Println(s)
		fmt.Printf("第 %d 天", in)
		fmt.Println()
	}

	if in > 10 {
		fmt.Println("变量大于10")
	} else {
		fmt.Println("变量小于10")
	}

	if len(s) > 0 {
		fmt.Println("变量不是空")
	} else {
		fmt.Println("变量是空")
	}

}
